package com.ygqh.baby.service.task.impl;

import com.foxinmy.weixin4j.mp.message.TemplateMessage;
import com.foxinmy.weixin4j.tuple.Text;
import com.foxinmy.weixin4j.util.StringUtil;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.constant.Constant;
import com.ygqh.baby.mapper.YgUserBalanceDetailMapper;
import com.ygqh.baby.model.*;
import com.ygqh.baby.po.*;
import com.ygqh.baby.service.*;
import com.ygqh.baby.service.task.YgAsynClient;
import com.ygqh.baby.service.task.YgRepairDataService;
import com.ygqh.baby.service.task.YgTaskService;
import com.ygqh.baby.utils.DateConvertUtils;
import com.ygqh.baby.utils.ExceptionUtil;
import com.ygqh.baby.utils.YgStringUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

@Service
public class YgTaskServiceImpl implements YgTaskService {
    protected final Logger logger = Logger.getLogger(this.getClass());

    @Autowired
    private YgProductService productService;
    @Autowired
    private YgOrderService orderService;
    @Autowired
    private SmsService smsService;
    @Autowired
    private YgUserService ygUserService;
    @Autowired
    private WxMpMessageService wxMpMessageService;
    @Autowired
    private YgUserBalanceService ygUserBalanceService;
    @Autowired
    private WxMpAuthorityService wxMpAuthorityService;
    @Autowired
    private YgProductCommentService productCommentService;
    @Autowired
    private YgOrderLogService ygOrderLogService;
    @Autowired
    private YgTaskTimeService ygTaskTimeService;
    @Autowired
    private YgGroupBuyingService ygGroupBuyingService;
    @Autowired
    private YgAsynClient ygAsynClient;
    @Value("${promotion.link}")
    protected String promotionLink;
    @Value("${cps.share.commission.rate}")
    protected BigDecimal shareCommissionRate;
    @Value("${cps.forever.commission.rate}")
    protected BigDecimal foreverCommissionRate;
    @Value("${wdt.shopName}")
    protected String shopName;
    @Autowired
    private YgUserBalanceService userBalanceService;
    @Autowired
    private YgUserBalanceDetailService ygUserBalanceDetailService;
    @Autowired
    private LogService logService;
    @Autowired
    private YgCouponDetailService couponDetailService;
    @Autowired
    private YgUserBalanceDetailMapper userBalanceDetailMapper;
    @Autowired
    private WxMpMessageService messageService;

    @Autowired
    private YgChannelService channelService;
    @Autowired
    private YgAddedUsersService addedUsersService;

    @Autowired
    private YgCouponService couponService;
    @Autowired
    private YgProductService ygProductService;
    @Autowired
    private YgReturnOrderService ygReturnOrderService;
    @Autowired
    private YgReturnOrderLogService ygReturnOrderLogService;
    @Autowired
    private YgUserCultivationDayService userCultivationDayService;
    @Autowired
    private YgUserBargainService ygUserBargainService;
    @Autowired
    private YgRepairDataService ygRepairDataService;
    @Autowired
    private YgUserMemberService ygUserMemberService;
    @Autowired
    private YgOrderDetailService ygOrderDetailService;
    @Autowired
    private YgPrepayBookRecordService ygPrepayBookRecordService;
    @Autowired
    private YgUserAuthsService ygUserAuthsService;
    @Autowired
    private WxSmallMessageService wxSmallMessageService;

    public void productStatusTask() {
        logger.debug("【productStatusTask】：开始执行更新商品上下架状态的定时任务... ");
        List<Long> ids = null;

        try {
            ids = productService.findProductNoStock();
            if (ids != null && ids.size() > 0) {
                productService.updateSaleStatusByTask(ids);
                // logger.error("【productStatusTask】：productIds=" +
                // ids.toString());
            } else {
                logger.debug("【productStatusTask】：没有需要下架商品... ");
            }

        } catch (Exception e) {
            logger.error("【productStatusTask】：商品上下架状态更新失败... 商品id ：" + ids.toString() + ";" + e.toString(), e);
            e.printStackTrace();
        }

        logger.debug("【productStatusTask】：更新商品上下架状态的定时任务执行成功....商品id ： " + ids.toString());

    }

    /**
     * 支付超时任务
     */
    public void orderStatusForCancelTask() {
        logger.debug("【orderStatusForCancelTask】：开始执行订单超时的定时任务.... ");
        Date currentDate = new Date();
        int row = 0;
        List<Long> orderIds = null;
        List<YgStock> stockList = null;
        List<YgCouponDetail> couponList = null;
        List<YgOrderLog> orderLogs = null;
        List<YgOrder> backAccountOrders = null;
        List<YgUserBalanceDetail> accountDetail = null;
        Date currentTime = new Date();
        try {
            List<YgOrder> orderList = orderService.findOrderIdForCancelTask(DateConvertUtils.addDay(currentDate, -1));
            orderIds = new ArrayList<Long>();
            stockList = new ArrayList<YgStock>();
            couponList = new ArrayList<YgCouponDetail>();
            orderLogs = new ArrayList<YgOrderLog>();
            if (orderList != null && orderList.size() > 0) {
                for (YgOrder order : orderList) {
                    orderIds.add(order.getOrderId());
                    if (order.getOrderDetail() != null) {
                        for (YgOrderDetail detail : order.getOrderDetail()) {
                            YgStock stock = new YgStock();
                            stock.setSkuCode(detail.getSkuCode());
                            stock.setAmount(detail.getQuantity());
                            stockList.add(stock);
                        }
                    }

                    if (order.getCouponDetailId() != null) {
                        YgCouponDetail ygCouponDetail = new YgCouponDetail();
                        ygCouponDetail.setId(order.getCouponDetailId());
                        ygCouponDetail.setUseStatus(CouponStatus.Received);
                        couponList.add(ygCouponDetail);
                    }
                    if (order.getAccountPrice().compareTo(new BigDecimal("0.00")) > 0) {
                        if (CollectionUtils.isEmpty(accountDetail)) {
                            backAccountOrders = new ArrayList<YgOrder>();
                            accountDetail = new ArrayList<YgUserBalanceDetail>();
                        }
                        backAccountOrders.add(order);

                        YgUserBalanceDetail record = new YgUserBalanceDetail();
                        record.setUserId(order.getUserId());
                        record.setOrderId(order.getOrderId().toString());
                        record.setPriceType(BalanceType.Balance);
                        record.setBalancePrice(order.getAccountPrice());
                        record.setOperation(OperationType.CancelOrder.getTitle());
                        record.setOperationType(OperationType.CancelOrder);
                        record.setCreateTime(new Date());
                        record.setRemark("system");
                        record.setPlatformNo(order.getPlatformNo());
                        accountDetail.add(record);

                    }
                    YgOrderLog log = new YgOrderLog();
                    log.setOrderId(order.getOrderId());
                    log.setOrderStatus(OrderStatus.TradeClosed);
                    log.setCreateBy("系统定时任务");
                    log.setRemark("定时任务，订单支付超时，取消订单;" + order.getAccountPrice());
                    log.setCreateTime(currentTime);
                    orderLogs.add(log);
                }
                // 更新订单状态
                row = orderService.cancelOrderByTask(orderIds, "时间超时");
                // 还库存
                // stockService.backStock(stockList);
                // 还优惠卷
                couponDetailService.updateBatch(couponList);
                // 还红包
                userBalanceService.backAcountPriceBatch(backAccountOrders);

                userBalanceService.addBalacneDetailByBatch(accountDetail);
                // 记录操作日志
                ygOrderLogService.addOrderLogBatch(orderLogs);
                // 异步处理绑定订单的活动记录
                ygPrepayBookRecordService.asyncUpdateRecordByCancelOrder(orderIds);
            } else {
                logger.debug("【orderStatusForCancelTask】：没有支付超时的订单" + "影响行数 ：" + row);
            }

            logger.debug("【orderStatusForCancelTask】：执行订单超时的定时任务结束.... 订单ids" + orderIds.toString());
        } catch (Exception e) {
            logger.error("【orderStatusForCancelTask】：执行订单超时任务失败" + "订单ids" + orderIds.toString() + ";" + e.toString(), e);
            e.printStackTrace();
        }

    }

    /**
     * 对于快要支付超时的订单，发消息提醒用户支付。（订单提交后1小时发送）
     */

    public void sendPayInvitation() {
        logger.debug("【sendPayInvitation】：开始执行支付邀请的定时任务.... ");
        try {
            List<YgOrder> orderList = orderService.findOrderForSendPayInvitation(5);
            for (YgOrder order : orderList) {
                YgUser ygUser = ygUserService.findById(order.getUserId());

                // 推送壹家店小程序消息
                if (Constant.YIJIADIAN_PLATFORM_NO.equals(order.getPlatformNo())) {
                    Message msg = wxSmallMessageService.sendWaitingPayMessage(order);
                    if (msg.getType().equals(Message.Type.error)) {
                        logger.debug("【sendPayInvitation】：发送小程序支付邀请失败....订单编号:" + order.getOrderId());
                    }
                    continue;
                }

                // 推送小程序消息
                if (ygUser.getSmallOpenId() != null && order.getFormId() != null) {
                    Message msg = wxMpMessageService.sendWaitingPay$Samll(order, ygUser.getSmallOpenId());
                    if (msg.getType().equals(Message.Type.error)) {

                        logger.debug("【sendPayInvitation】：发送小程序支付邀请失败....订单编号:" + order.getOrderId());
                    }
                }

                // 推送微信消息
                logger.debug("【sendPayInvitation】：发送微信支付邀请....订单编号:" + order.getOrderId());
                if (ygUser.getOpenId() != null) {
                    TemplateMessage tplMessage = wxMpMessageService.getTemplateMessageInfo(order, ygUser, WxMessageType.PayInvitation);

                    Message message = wxMpMessageService.sendTemplateMessage(tplMessage);
                    if (message.getType().equals(Message.Type.error)) {

                        logger.debug("【sendPayInvitation】：发送微信支付邀请失败....订单编号:" + order.getOrderId());
                    }
                }
                // 发送手机短信
                if (YgStringUtils.isChinaPhoneLegal(ygUser.getUserName())) {

//                    String url = promotionLink + "/user/orderdetail.html?orderId=" + order.getOrderId();
//                    url = wxMpAuthorityService.getShortUrl(url);
                    String content;
                    if (Constant.YIJIADIAN_PLATFORM_NO.equals(order.getPlatformNo())) {
                        content = "亲，您还有需要付款的订单，可到\"壹家店\"进行支付。订单提交后24小时内有效。";
                    } else {
                        content = "亲，您还有需要付款的订单, 请到\"壹果商城\"进行支付。订单提交后24小时内有效。";
                    }
                    logger.debug("发送手机支付邀请....订单编号:" + order.getOrderId());
                    smsService.sendSms(ygUser.getUserName(), content);
                }

            }
            if (orderList == null || orderList.size() == 0) {

                logger.debug("【sendPayInvitation】：没有待发送支付邀请的订单.... ");
            }
        } catch (Exception e) {
            logger.error("【sendPayInvitation】：发送支付邀请服务实行失败.... " + ";" + ExceptionUtil.getExceptionMsg(e));
            e.printStackTrace();
        }
        logger.debug("【sendPayInvitation】：执行支付邀请的定时任务结束.... ");

    }

    public void orderStatusForSuccessTask() {
        logger.debug("【orderStatusForSuccessTask】：开始执行发货7天后，订单自动更新为交易成功状态的定时任务....  ");
        int row = 0;
        Date currentTime = new Date();
        try {
            List<Long> orderIds = new ArrayList<Long>();
            List<YgOrder> list = orderService.findOrder4SuccessTask(DateConvertUtils.addDay(currentTime, -7));

            Map<Long, List<YgOrder>> subDetailMap = new LinkedHashMap<Long, List<YgOrder>>();
            List<Long> userIds = new ArrayList<Long>();

            if (list != null && list.size() > 0) {
                for (YgOrder order : list) {
                    // 部分发货获取存在换货
                    if (order.getExpressCode() == null || order.getExpressCode().equals("true") || order.getHasReturnOrChange()) {
                        continue;
                    }

                    orderIds.add(order.getOrderId());
                    List<YgOrder> subDetails = subDetailMap.get(order.getUserId());
                    if (subDetails == null) {
                        subDetails = new ArrayList<YgOrder>();
                        subDetailMap.put(order.getUserId(), subDetails);
                        userIds.add(order.getUserId());
                    }
                    subDetails.add(order);

                }
            }
            if (userIds.size() > 0) {
                row = orderService.orderStatusForSuccessTask(orderIds);
                for (Long userId : userIds) {
                    List<YgOrder> orderList = subDetailMap.get(userId);
                    YgUser user = ygUserService.findById(userId);
                    try {
                        sendOrderSuccessMsg(user, orderList);
                    }catch (Exception e ){
                        e.printStackTrace();
                        logger.error("发送消息失败");
                    }

                }
            }
            ygTaskTimeService.saveOrUpdate(TaskMethod.OrderStatusForSuccessTask.name(), currentTime, "执行成功");

        } catch (Exception e) {
            logger.error("【orderStatusForSuccessTask】：开始执行发货7天后，订单自动更新为交易成功状态的定时任务失败....  " + ";" + ExceptionUtil.getExceptionMsg(e));
            e.printStackTrace();
        }
        logger.debug("【orderStatusForSuccessTask】：开始执行发货7天后，订单自动更新为交易成功状态的定时任务成功....  row = " + row);
    }

    private void sendOrderSuccessMsg(YgUser user, List<YgOrder> orderList) {

        String url = promotionLink + "/user/orderlist.html?orderStatus=TradeSuccess";
        String title = "亲，快去壹果评价吧，评价完成后您将收到1张优惠券！";


        YgOrder ygOrder = orderService.findOrderDetailByOrderId(orderList.get(0).getOrderId());
        String keyword1 = "";
        String keyword2 = "";
        if (orderList.size() > 1) {

            keyword1 = ygOrder.getOrderId().toString() + " 等";
        } else {
            keyword1 = ygOrder.getOrderId().toString();

        }
        keyword2 = DateConvertUtils.format(DateConvertUtils.addDay(ygOrder.getConfirmReceiveTime(), -1));
        String remark = "商品详情：" + ygOrder.getOrderDetail().get(0).getProductName() + " 等商品。";

        wxMpMessageService.sendOrderSuccessMsg(user, url, title, remark, new String[]{keyword1, keyword2});

        if (YgStringUtils.isChinaPhoneLegal(user.getUserName())) {
//            String shortUrl = wxMpAuthorityService.getShortUrl(url);
            smsService.sendSms(user.getUserName(), title);
        }
    }

    public void returnOrderForCompleteTask() {
        logger.debug("【returnOrderForCompleteTask】：开始执行发货7天后，订单自动更新为交易成功状态的定时任务....  ");
        Date currentTime = new Date();
        int row = 0;
        try {
            List<String> returnCodes = new ArrayList<String>();
            List<YgReturnOrder> list = ygReturnOrderService.findOrderForComplete(DateConvertUtils.addDay(currentTime, -7));

            Map<Long, List<YgReturnOrder>> subDetailMap = new LinkedHashMap<Long, List<YgReturnOrder>>();
            List<Long> userIds = new ArrayList<Long>();

            if (list != null && list.size() > 0) {
                for (YgReturnOrder order : list) {

                    // 部分发货
                    if (order.getSendCount() == null || order.getSendCount().intValue() < order.getReturnOrderDetails().size()) {
                        continue;
                    }
                    returnCodes.add(order.getReturnCode());
                    List<YgReturnOrder> subDetails = subDetailMap.get(order.getUserId());
                    if (subDetails == null) {
                        subDetails = new ArrayList<YgReturnOrder>();
                        subDetailMap.put(order.getUserId(), subDetails);
                        userIds.add(order.getUserId());
                    }
                    subDetails.add(order);

                }
            }
            if (returnCodes.size() > 0) {
                row = ygReturnOrderService.returnOrderForCompleteTask(returnCodes);
                ygReturnOrderLogService.addReturnOrderLogBatch(returnCodes, "发货后7天完成，感谢您对我们工作的支持。", ReturnStatus.Complete, "returnOrderForCompleteTask");
            }
            ygTaskTimeService.saveOrUpdate(TaskMethod.ReturnOrderForCompleteTask.name(), currentTime, "执行成功");

        } catch (Exception e) {
            logger.error("【returnOrderForCompleteTask】：开始执行换货单发货7天后，订单自动更新为完成状态的定时任务失败....  " + ";" + e.toString(), e);
            e.printStackTrace();
        }
        logger.debug("【returnOrderForCompleteTask】：开始执行换货单发货7天后，订单自动更新为完成状态的定时任务成功....  row = " + row);
    }

    @Override
    public void returnOrderForCancelTask() {
        Date currentTime = new Date();
        try {
            List<OrderReturnInfo> list = ygReturnOrderService.findReOrder4Cancel(DateConvertUtils.addDay(currentTime, -10));
            if (list != null && list.size() > 0) {
                List<String> returnCodes = new ArrayList<String>();
                List<Long> oIds = new ArrayList<>();
                for (OrderReturnInfo order : list) {
                    returnCodes.add(order.getReturnCode());
                    List<OrderDetailReturnInfo> odList = order.getOdList();
                    List<Long> collect = odList.stream().map(od -> od.getOid()).collect(Collectors.toList());
                    oIds.addAll(collect);
                }
                ygReturnOrderService.updateReOrderForCancel(returnCodes);
                ygOrderDetailService.cancelRefundMarkByOids(oIds);
                ygReturnOrderLogService.addReturnOrderLogBatch(returnCodes, "您的订单已超出10日没有退货，申请已自动关闭。", ReturnStatus.Cancel, "returnOrderForCancelTask");
            }

            ygTaskTimeService.saveOrUpdate(TaskMethod.ReturnOrderForCancelTask.name(), currentTime, "执行成功");
        } catch (Exception e) {
            logger.error("【returnOrderForCancelTask】：开始执退换货申请单10天后未提交退货，订单自动取消的定时任务失败....  " + ";" + e.toString(), e);
            e.printStackTrace();
        }

    }

    @Override
    public void employeeToEmployer() {
        List<YgChannelBalance> channelList = channelService.findAllChildChannel();

        for (YgChannelBalance childChannel : channelList) {
            if (childChannel.getUserId() == null || childChannel.getBalancePrice().compareTo(new BigDecimal(0)) == 0)
                continue;

            Long parentId = childChannel.getParentId();
            YgChannelBalance channelBalance = channelService.findChannelBalanceByParentId(parentId);
            Long parentUserId = channelBalance.getUserId();
            Long childUserId = childChannel.getUserId();
            BigDecimal childBalancePrice = childChannel.getBalancePrice();

            YgUserBalance userBalance = userBalanceService.findByUserId(childUserId);
            // //把员工的可提现金额转换成已提现

            // 转出员工可已现金额
            userBalance.setBalancePrice(userBalance.getBalancePrice().subtract(childBalancePrice));
            userBalance.setUpdateTime(new Date());
            userBalanceService.update(userBalance);
            YgUserBalanceDetail childDetail = new YgUserBalanceDetail();
            childDetail.setBalancePrice(new BigDecimal(0).subtract(childBalancePrice));
            childDetail.setUserId(childChannel.getUserId());
            childDetail.setPriceType(BalanceType.Balance);
            childDetail.setOperation("转出");
            childDetail.setRemark("转出员工可已现金额到领导账户");
            childDetail.setCreateTime(new Date());
            childDetail.setRebateType(RebateType.Share);
            userBalanceDetailMapper.insert(childDetail);

            // 增加领导账户可提现金额
            YgUserBalance parentUserBalance = userBalanceService.findByUserId(parentUserId);
            parentUserBalance.setBalancePrice(parentUserBalance.getBalancePrice().add(childBalancePrice));
            parentUserBalance.setUpdateTime(new Date());
            userBalanceService.update(parentUserBalance);
            YgUserBalanceDetail balanceDetail = new YgUserBalanceDetail();
            balanceDetail.setBalancePrice(childBalancePrice);
            balanceDetail.setUserId(parentUserId);
            balanceDetail.setPriceType(BalanceType.Balance);
            balanceDetail.setOperation("转入(" + childChannel.getUserName() + ")");
            balanceDetail.setRemark("新增员工可提现金额到领导账户");
            balanceDetail.setCreateTime(new Date());
            balanceDetail.setRebateType(RebateType.Share);
            userBalanceDetailMapper.insert(balanceDetail);
        }

    }

    @Deprecated
    @Override
    public void productCommentTask() {
        logger.debug("【productCommentTask】：开始执交易成功后7天如果用户没有评论，系统自动好评....  ");
        Date currentDate = new Date();
        List<Comment4TaskModel> list = orderService.findProductComment4Task(DateConvertUtils.addDay(currentDate, -7));
        if (list != null && list.size() > 0) {
            for (Comment4TaskModel item : list) {
                if (item.getCommentId() == null) {
                    try {
                        if (item.getProductId() == null) {
                            continue;
                        }
                        productCommentService.commentOrderItem(item.getOrderId(), item.getUserId(), item.getProductId(), item.getSkuId(), "好评！", null,
                                new CommentTag[]{CommentTag.HenZan}, 0L);

                    } catch (Exception e) {
                        logger.error("【productCommentTask】：执行自动评论--报错：....orderId=" + item.getOrderId() + ";skuId=" + item.getSkuId() + ";" + e.toString(), e);
                        e.printStackTrace();
                        continue;
                    }
                }
            }
        }
        logger.debug("【productCommentTask】：执行交易成功后7天如果用户没有评论，系统自动好评 成功....  ");
    }

    public void balanceTask(Integer day) {
        logger.debug("【balanceTask】：开始执行预收入的定时任务....  ");

        try {
            if (day == null)
                day = 2;
            List<YgOrder> orderList = orderService.findOrderForBalaceTask(day);
            // List<YgOrder> cancelOrderList =
            // orderService.findCancelOrderForBalaceTask(day);
            List<YgOrder> returnOrderList = orderService.findReturnOrderForBalaceTask(day);
            // 普通订单
            calculateBalanceTask(orderList, "order");
            // 取消订单
            // calculateBalanceTask(cancelOrderList, "cancelOrder");

            // 退货订单
            calculateBalanceTask(returnOrderList, "returnOrder");

        } catch (Exception e) {
            logger.error("【balanceTask】发生异常;" + e.getMessage(), e);
            e.printStackTrace();
            throw e;
        }
        ygTaskTimeService.saveOrUpdate(TaskMethod.PreBalanceTask.name(), new Date(), "预收入执行成功");
        logger.debug("【balanceTask】：预收入的定时任务执行成功.... ");

    }

    public void sendRedPacket() {

        try {
            Date parse = DateConvertUtils.parse("2017-04-06", "yyy-MM-dd");

            Date startDate = DateConvertUtils.addDay(parse, -15);
            Date endDate = parse;
            endDate = DateConvertUtils.formatToDate(endDate, "yyy-MM-dd");
            List<YgOrder> orders = orderService.findFirstOrderList(startDate, endDate);
            orders.forEach(o -> {
                YgOrder firstOrder = orderService.findFirstOrder(o.getUserId(), null);
                if (o.getOrderId().equals(firstOrder.getOrderId())) {
                    YgUser user = ygUserService.findById(o.getUserId());
                    if (user != null && StringUtils.isNotBlank(user.getFromCode())) {
                        YgUser fromUser = ygUserService.findBySourceCode(user.getFromCode());
                        if (fromUser != null) {
                            YgUserBalanceDetail detail = ygUserBalanceDetailService.findRedPacketRechargeByOrderId(o.getOrderId());
                            if (detail == null) {
                                userBalanceService.redPacketRecharge(fromUser.getUserName(), new BigDecimal(20), o.getOrderId() + "", fromUser.getUserName());
                            }
                            // wxMpMessageService.sendRedPacketMessage(fromUser.getId(),
                            // user.getNickName());
                        }
                    }
                }

            });
            ygTaskTimeService.saveOrUpdate("sendRedPacket", new Date(), "执行成功");
        } catch (Exception e) {
            logger.error("【sendRedPacket】发生异常", e);
        }

    }

    public void calculateBalanceTask(List<YgOrder> list, String orderType) {

        List<YgUserBalanceDetail> detailList = new ArrayList<>();
        List<Long> userIds = new ArrayList<>();
        for (YgOrder order : list) {
            Boolean firstAward = false;
            if (StringUtil.isNotBlank(order.getSourceCode()) && order.getSourceCode().startsWith("1")) {
                // 分享首单双方获得9元成长基金
                YgUser user = ygUserService.findBySourceCode(order.getSourceCode());

                firstAward = firstSingleAward(user, order, detailList, userIds, orderType);

                if (!firstAward) {
                    doPreBalance(order, user, detailList, userIds, orderType, RebateType.Share);
                }

            }
            // 永久返利
            if (!firstAward) {

                YgUser user = ygUserService.findById(order.getUserId());
                if (user != null && StringUtils.isNotBlank(user.getFromCode())) {
                    user = ygUserService.findBySourceCode(user.getFromCode());
                    this.doPreBalance(order, user, detailList, userIds, orderType, RebateType.Forever);

                }
            }

        }

        if (detailList.size() > 0) {
            // 插入详情表
            try {
                int row = ygUserBalanceService.addBalacneDetailByBatch(detailList);
            } catch (Exception e) {
                logger.error("【balanceTask】：向yg_user_balance_detail 表中插入数据 失败....  detailList ：" + detailList.toString(), e);
                e.printStackTrace();
                throw e;
            }

        }
        if (userIds.isEmpty()) {
            return;
        }
        List<YgUserBalance> balanceList = userBalanceDetailMapper.findUbdSumByUserIds(userIds, BalanceType.PreIncome);
        try {
            if (CollectionUtils.isNotEmpty(balanceList)) {
                ygUserBalanceService.updateUserBalanceByTask(balanceList);
            }

            if (orderType.equals("order")) {
                // 发送消息
                sendRebateMessage(detailList, BalanceType.PreIncome);
            }

        } catch (Exception e) {
            logger.error("【balanceTask】：回写yg_user_balance....更新预收入金额 ...失败 ....balanceList: " + balanceList.toString(), e);
            e.printStackTrace();
            throw e;
        }
    }

    private void doPreBalance(YgOrder order, YgUser user, List<YgUserBalanceDetail> detailList, List<Long> userIds, String orderType, RebateType rebateType) {
        // 分享返利
        if (user != null && user.getIsSeller()) {
            String relationId = null;
            if (orderType.equals("order")) {
                relationId = order.getOrderId().toString();
            } else {
                relationId = order.getReturnCode();
            }
            // 去重
            String dbOrderId = userBalanceDetailMapper.selectBalanceDetailByOrderId(BalanceType.PreIncome, rebateType, relationId.toString());
            if (dbOrderId == null) {
                YgUserBalanceDetail balanceDetail = new YgUserBalanceDetail();

                BigDecimal rate = rebateType.equals(RebateType.Share) ? user.getShareRate() : user.getForeverRate();
                YgChannel channel = channelService.findByCode(user.getSourceCode());
                if (channel != null) {
                    setBaLanceDetail(balanceDetail, user, order, channel.getCommissionRate(), rebateType, orderType, BalanceType.PreIncome);
                } else {
                    setBaLanceDetail(balanceDetail, user, order, rate, rebateType, orderType, BalanceType.PreIncome);
                }
                detailList.add(balanceDetail);
                userIds.add(user.getId());
            }
        }
    }

    private Boolean firstSingleAward(YgUser user, YgOrder order, List<YgUserBalanceDetail> detailList, List<Long> userIds, String orderType) {
        if (user != null) {
            if (user.getUserType().equals(UserType.Agent)) {
                return false;
            }
            YgUser orderUser = ygUserService.findById(order.getUserId());
            if (order.getSourceCode().equals(orderUser.getSourceCode())) {
                return false;
            }
            YgOrder firstOrder = orderService.findFirstOrder(order.getUserId(), null);
            if (firstOrder != null && firstOrder.getOrderId().equals(order.getOrderId()) && !order.getPayType().equals(PayType.Account)) {

                String relationId = null;
                BigDecimal inComePrice = null;
                if (orderType.equals("order")) {
                    relationId = order.getOrderId().toString();
                    inComePrice = new BigDecimal("9.00");
                } else if (orderType.equals("returnOrder")) {
                    if (order.getTotalPrice().equals(firstOrder.getTotalPrice())) {
                        relationId = order.getReturnCode();
                        inComePrice = new BigDecimal("-9.00");
                    } else {
                        return true;
                    }
                }
                int count = ygUserBalanceDetailService.countByOrderId(relationId, BalanceType.PreIncome, RebateType.FirstAward);

                if (count == 0) {
                    YgUserBalanceDetail balanceDetail = new YgUserBalanceDetail();
                    balanceDetail.setUserId(user.getId());
                    balanceDetail.setPriceType(BalanceType.PreIncome);
                    balanceDetail.setRebateType(RebateType.FirstAward);
                    balanceDetail.setOperationType(OperationType.FirstAward);
                    balanceDetail.setOperation(OperationType.FirstAward.getTitle());
                    balanceDetail.setIncomePayPrice(inComePrice);
                    balanceDetail.setOrderId(relationId);
                    balanceDetail.setOrderPrice(order.getTotalPrice());
                    balanceDetail.setRemark("预收入");
                    balanceDetail.setCreateTime(new Date());
                    balanceDetail.setCreateBy("firstSingleAward");

                    YgUserBalanceDetail clone = balanceDetail.clone();
                    clone.setUserId(order.getUserId());

                    detailList.add(clone);
                    detailList.add(balanceDetail);
                    userIds.add(clone.getUserId());
                    userIds.add(balanceDetail.getUserId());
                }
                return true;
            }
        }
        return false;

    }

    private void setBaLanceDetail(YgUserBalanceDetail balanceDetail, YgUser user, YgOrder order, BigDecimal rate, RebateType rebateType, String orderType,
                                  BalanceType balanceType) {
        // 如果是退货单
        BigDecimal price = new BigDecimal(0);
        if (orderType.equals("order")) {
            balanceDetail.setOrderId(order.getOrderId() + "");
            if (rebateType.equals(RebateType.Forever)) {
                balanceDetail.setOperation(OperationType.Forever.getTitle());
                balanceDetail.setOperationType(OperationType.Forever);
            } else {
                balanceDetail.setOperation(OperationType.Share.getTitle());
                balanceDetail.setOperationType(OperationType.Share);
            }
            price = order.getTotalPrice().multiply(rate).setScale(2, BigDecimal.ROUND_HALF_UP);
        } else if (orderType.equals("returnOrder")) {
            YgUserBalanceDetail detail = ygUserBalanceService.findBalanceDetail(user.getId(), order.getOrderId(), rebateType, balanceType);
            if (detail != null) {
                price = order.getTotalPrice().multiply(detail.getCommissionRate()).setScale(2, BigDecimal.ROUND_HALF_UP);
                price = new BigDecimal(0).subtract(price);
                balanceDetail.setOrderId(order.getReturnCode());
                balanceDetail.setOperation(OperationType.Return.getTitle());
                balanceDetail.setOperationType(OperationType.Return);
            } else {
                // logger.error("订单：" + order.getOrderId() + "没有" + rebateType +
                // "型" + balanceType);
            }
        }
        balanceDetail.setUserId(user.getId());
        balanceDetail.setOrderPrice(order.getTotalPrice());
        balanceDetail.setPriceType(balanceType);
        if (balanceType.equals(BalanceType.PreIncome)) {
            balanceDetail.setIncomePayPrice(price);
            balanceDetail.setRemark("预收入");
        } else {
            balanceDetail.setBalancePrice(price);
            balanceDetail.setRemark("可提现");
        }
        balanceDetail.setCommissionRate(rate);
        balanceDetail.setCreateTime(new Date());
        balanceDetail.setRebateType(rebateType);
    }

    // 发送消息
    private void sendRebateMessage(List<YgUserBalanceDetail> detailList, BalanceType balanceType) {
        try {
            detailList.forEach(d -> {
                YgOrder o = new YgOrder();
                if ((d.getIncomePayPrice().compareTo(new BigDecimal(0)) > 0 && balanceType.equals(BalanceType.PreIncome))
                        || (balanceType.equals(BalanceType.Balance) && d.getBalancePrice().compareTo(new BigDecimal(0)) > 0)) {
                    o.setOrderId(Long.valueOf(d.getOrderId()));
                    o.setCreateTime(new Date());
                    BigDecimal price = d.getIncomePayPrice();

                    YgUser u = ygUserService.findById(d.getUserId());
                    String title = "亲，您有新的" + balanceType.getTitle() + "了。";
                    String remark = "可以到\"预计成长基金\"查看哦";

                    if (balanceType.equals(BalanceType.Balance)) {
                        price = d.getBalancePrice();
                        if (u.getUserType().equals(UserType.UserAgent)) {

                            remark = "可以到\"可提现金额\"查看哦";
                        } else {
                            remark = "可以到\"成长基金\"查看哦";
                        }

                    } else {
                        price = d.getIncomePayPrice();
                        if (u.getUserType().equals(UserType.UserAgent)) {

                            remark = "可以到\"预计收入\"查看哦";
                        } else {
                            remark = "可以到\"预计成长基金\"查看哦";
                        }
                    }

                    messageService.sendRebateMessage(o, u, price, title, remark, d.getOperationType());
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public void preIncomeToBalance() {

        Date currentDate = new Date();
        Date lastRunDate = new Date();
        logger.debug("开始执行预收入金额转换成可提现金额定时任务....  ");
        long diffDates = 0L;
        YgTaskTime taskTime = ygTaskTimeService.findLastByTaskMethod(TaskMethod.PreIncomeToBalance);
        if (taskTime != null) {
            // 获取最后一次执行时间与当前时间的间隔几天
            diffDates = DateConvertUtils.diffDayes(taskTime.getRunTime(), new Date());
            lastRunDate = taskTime.getRunTime();
        } else {
            lastRunDate = DateConvertUtils.addDay(new Date(), -1);
        }
        if (diffDates > 0) {
            Date startDate = DateConvertUtils.addDay(lastRunDate, -15);
            Date endDate = DateConvertUtils.addDay(new Date(), -15);
            // 获取发货十五天后的订单
            List<YgOrder> orderList = orderService.findOrderFor30Day(startDate, endDate);
            calculatePreIncomeToBalance(orderList, "order");

            ygTaskTimeService.saveOrUpdate(TaskMethod.PreIncomeToBalance.name(), currentDate, "执行成功！");
        }
    }

    private void calculatePreIncomeToBalance(List<YgOrder> orderList, String orderType) {
        try {

            List<Long> userIds = new ArrayList<>();
            List<YgUserBalanceDetail> detailList = new ArrayList<>();
            List<YgUserBalanceDetail> details4OrderUser = new ArrayList<>();
            for (YgOrder order : orderList) {

                // 如果存在退货完成的订单，可提现金额需减去退货的那部分
                BigDecimal residualRefundPrice = ygReturnOrderService.residualRefundPriceOnlyPaid(order.getOrderId());
                order.setTotalPrice(residualRefundPrice);

                doOrderReward(order, detailList, details4OrderUser, userIds);

                Boolean firstAward = doOrderFirstAward(order, detailList, details4OrderUser, userIds, orderType, RebateType.FirstAward);
                if (!firstAward) {

                    doOrderBalance(order, detailList, details4OrderUser, userIds, orderType, RebateType.Share);
                    doOrderBalance(order, detailList, details4OrderUser, userIds, orderType, RebateType.Forever);
                }

            }
            if (detailList.size() > 0) {
                logger.debug("【preIncomeToBalance】：向yg_user_balance_detail 表中插入数据.... ");
                try {
                    ygUserBalanceService.addBalacneDetailByBatch(detailList);
                } catch (Exception e) {
                    // logger.error("【preIncomeToBalance】：向yg_user_balance_detail
                    // 表中插入数据 失败....", e);
                    throw e;
                }
            }
            if (userIds.isEmpty()) {
                return;
            }
            List<YgUserBalance> balanceList = userBalanceDetailMapper.findUbdSumByUserIds(userIds, BalanceType.Balance);

            try {
                if (CollectionUtils.isNotEmpty(balanceList)) {
                    ygUserBalanceService.updateUserBalancePrice(balanceList);
                }
            } catch (Exception e) {

                logger.error("【30天后预收入金额转换成可提现金额定时任务】：回写yg_user_balance....更新可提现金额（账户余额） ...失败 ....", e);
                throw e;
            }

            this.sendRebateMessage(details4OrderUser, BalanceType.Balance);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("【preIncomeToBalance】发生异常....  ", e);
            throw e;
        }
        logger.debug("【preIncomeToBalance】30天后预收入金额转换成可提现金额定时任务结束....  ");
    }

    private Boolean doOrderFirstAward(YgOrder order, List<YgUserBalanceDetail> detailList, List<YgUserBalanceDetail> details4OrderUser, List<Long> userIds,
                                      String orderType, RebateType firstaward) {

        int hasPre = ygUserBalanceDetailService.countByOrderId(order.getOrderId().toString(), BalanceType.PreIncome, RebateType.FirstAward);

        if (hasPre > 0) {

            if (order.getTotalPrice().compareTo(new BigDecimal("0.00")) > 0) {

                int count = ygUserBalanceDetailService.countByOrderId(order.getOrderId().toString(), BalanceType.Balance, RebateType.FirstAward);
                if (count == 0) {

                    YgUser shareUser = ygUserService.findBySourceCode(order.getSourceCode());

                    if (shareUser != null) {

                        BigDecimal balancePrice = new BigDecimal("9.00");
                        YgUserBalanceDetail balanceDetail = new YgUserBalanceDetail();
                        balanceDetail.setUserId(shareUser.getId());
                        balanceDetail.setPriceType(BalanceType.Balance);
                        balanceDetail.setRebateType(RebateType.FirstAward);
                        balanceDetail.setOperationType(OperationType.FirstAward);
                        balanceDetail.setOperation(OperationType.FirstAward.getTitle());
                        balanceDetail.setBalancePrice(balancePrice);
                        balanceDetail.setOrderId(order.getOrderId().toString());
                        balanceDetail.setOrderPrice(order.getTotalPrice());
                        balanceDetail.setRemark("可提现");
                        balanceDetail.setCreateTime(new Date());
                        balanceDetail.setCreateBy("doOrderFirstAward");

                        YgUserBalanceDetail clone = balanceDetail.clone();
                        clone.setUserId(order.getUserId());

                        detailList.add(clone);
                        detailList.add(balanceDetail);
                        userIds.add(balanceDetail.getUserId());
                        userIds.add(clone.getUserId());

                    }
                }
            }
            return true;
        }
        return false;

    }

    private void doOrderBalance(YgOrder order, List<YgUserBalanceDetail> detailList, List<YgUserBalanceDetail> details4OrderUser, List<Long> userIds,
                                String orderType, RebateType rebateType) {
        if (StringUtil.isNotBlank(order.getSourceCode())) {
            String shareOrderId = userBalanceDetailMapper.selectBalanceDetailByOrderId(BalanceType.Balance, rebateType, order.getOrderId() + "");
            if (shareOrderId == null) {
                YgUser user = null;
                if (rebateType.equals(RebateType.Share)) {

                    user = ygUserService.findBySourceCode(order.getSourceCode());
                } else if (rebateType.equals(RebateType.Forever)) {
                    YgUser orderUser = ygUserService.findById(order.getUserId());
                    user = ygUserService.findBySourceCode(orderUser.getFromCode());
                }
                if (user != null) {
                    // 获取预收入时的返利比例
                    YgUserBalanceDetail inComeDetail = ygUserBalanceService.findBalanceDetail(user.getId(), order.getOrderId(), RebateType.Share,
                            BalanceType.PreIncome);
                    if (inComeDetail == null) {
                        // logger.error("可提现服务报错；" + order.getOrderId() +
                        // ";该订单没有" + rebateType.getTitle() + "预收入");
                    } else {
                        // 分享返利
                        if (user != null && user.getIsSeller()) {
                            YgUserBalanceDetail balanceDetail = new YgUserBalanceDetail();
                            BigDecimal rate = inComeDetail.getCommissionRate();
                            setBaLanceDetail(balanceDetail, user, order, rate, rebateType, orderType, BalanceType.Balance);

                            detailList.add(balanceDetail);
                            userIds.add(user.getId());
                        }
                    }
                }
            }
        }
    }

    private void doOrderReward(YgOrder order, List<YgUserBalanceDetail> detailList, List<YgUserBalanceDetail> details4OrderUser, List<Long> userIds) {
        String rewardOrder = userBalanceDetailMapper.selectBalanceDetailByOrderId(BalanceType.Balance, RebateType.Reward, order.getOrderId() + "");
        if (rewardOrder == null) {
            // 用户下单，发货后15天，如果没有退货，奖励用户成长基金。
            YgUserMember member = ygUserMemberService.findByUserId(order.getUserId());
            BigDecimal rate = new BigDecimal("0.01");
            if (member != null && member.isMembersValid() && member.getMemberStartTime().before(order.getCreateTime())) {
                rate = new BigDecimal("0.02");
            }

            YgUserBalanceDetail rewardDetail = new YgUserBalanceDetail();
            rewardDetail.setBalancePrice(order.getTotalPrice().multiply(rate).setScale(2, BigDecimal.ROUND_HALF_UP));
            rewardDetail.setOperation(OperationType.Reward.getTitle());
            rewardDetail.setOperationType(OperationType.Reward);
            rewardDetail.setIncomePayPrice(new BigDecimal(0));
            rewardDetail.setOrderId(order.getOrderId() + "");
            rewardDetail.setCreateTime(new Date());
            rewardDetail.setCreateBy("system");
            rewardDetail.setPriceType(BalanceType.Balance);
            rewardDetail.setOrderPrice(order.getTotalPrice());
            rewardDetail.setUserId(order.getUserId());
            rewardDetail.setRebateType(RebateType.Reward);
            rewardDetail.setCommissionRate(rate);
            detailList.add(rewardDetail);
            details4OrderUser.add(rewardDetail);
            userIds.add(order.getUserId());
        }
    }

    @Override
    public void balanceTaskCheck() {

    }

    @Override
    public void calculateAddedUsers() {
        ygTaskTimeService.autoExecute(TaskMethod.CalculateAddedUsers.name(), new YgTaskTimeTemplate() {
            @Override
            public void execute(Date date) {
                try {
                    YgAddedUsers addedUsers = new YgAddedUsers();
                    Date startTime = DateConvertUtils.addDay(date, 0 - 1);
                    Date endTime = date;
                    addedUsers.setCreateTime(startTime);
                    // 新注册用户数
                    ResultSet<YgUser> resultSet = ygUserService.search(null, null, null, DateConvertUtils.addDay(date, 0 - 1), endTime, null, null, null, null);
                    addedUsers.setRegisteredUsersCount(resultSet.getTotal());
                    // 下单用户数
                    Long paidUsersCount = ygUserService.findPaidUsersCount(startTime, endTime);
                    addedUsers.setPaidUsersCount(paidUsersCount);

                    // 下单新用户数
                    Long paidNewUsersCount = ygUserService.findPaidNewUsersCount(startTime, endTime);
                    addedUsers.setPaidNewUsersCount(paidNewUsersCount);

                    addedUsersService.saveOrUpdate(addedUsers);
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("【calculateAddedUsers】:出现异常", e);

                }
            }
        });
    }

    @Override
    public void updateProductSaleNumAndCommentNum() {
        try {
            List<YgProductSaleNumAndCommentNumModel> list = ygProductService.findSaleNumAndCommentNum();
            ygProductService.updateProductSaleNumAndCommentNum(list);
        } catch (Exception e) {
            logger.error("updateProductSaleNumAndCommentNum 执行失败" + ExceptionUtil.getExceptionMsg(e));
            e.printStackTrace();
        }
    }

    @Override
    public void affiliateUserReport() {
        logger.debug("【affiliateUserReport】：" + DateConvertUtils.format(new Date()) + "- 开始执行生成代理用户耕耘报表...");
        ygTaskTimeService.execute(TaskMethod.AffiliateUserReport, 1, new YgTaskTimeTemplate() {
            @Override
            public void execute(Date date) {
                Date yesDay = DateConvertUtils.addDay(date, -1);
                String yesterday = DateConvertUtils.format(yesDay, "yyyy-MM-dd");
                try {

                    /**
                     * 查询订单集合
                     */
                    List<YgUserCultivationOrderPrice> orderPriceList = userCultivationDayService.findOrderPriceByDay(yesterday);

                    /**
                     * 查询退货集合
                     */
                    List<YgUserCultivationOrderPrice> returnPriceList = userCultivationDayService.findReturnPriceByDay(yesterday);

                    List<YgUserCultivationDay> onlyReturn = new ArrayList<YgUserCultivationDay>();
                    List<Long> userIds = new ArrayList<Long>();

                    List<YgUserCultivationDay> orderList = doBussness(orderPriceList, "order", userIds, onlyReturn, yesDay);
                    List<YgUserCultivationDay> returnList = doBussness(returnPriceList, "return", userIds, onlyReturn, yesDay);

                    orderList.forEach(o -> {
                        returnList.forEach(r -> {
                            if (o.getUserId().equals(r.getUserId())) {
                                o.setTotalPrice(o.getOrderPrice().subtract(r.getReturnPrice()));
                                o.setReturnPrice(r.getReturnPrice());
                            }
                        });
                    });
                    orderList.addAll(onlyReturn);

                    for (YgUserCultivationDay userCultivationDay : orderList) {
                        userCultivationDayService.save(userCultivationDay);
                    }
                    // ygTaskTimeService.saveOrUpdate(TaskMethod.AffiliateUserReport.name(),
                    // date, "正常");
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("【affiliateUserReport】:出现异常", e);
                    throw e;
                }
            }

        });
        logger.debug("【affiliateUserReport】：" + DateConvertUtils.format(new Date()) + "- 结束执行生成代理用户耕耘报表...");
    }

    private List<YgUserCultivationDay> doBussness(List<YgUserCultivationOrderPrice> list, String orderType, List<Long> userIds,
                                                  List<YgUserCultivationDay> onlyReturn, Date date) {

        List<YgUserCultivationDay> userCultiveationDayList = new ArrayList<YgUserCultivationDay>();
        /**
         * 订单用户ID分组
         */
        Map<Long, List<YgUserCultivationOrderPrice>> orderUserCultivationMap = list.stream().collect(Collectors.groupingBy(o -> o.getUserId()));
        /**
         * 用户订单集合
         */
        Iterator<Entry<Long, List<YgUserCultivationOrderPrice>>> it = orderUserCultivationMap.entrySet().iterator();
        while (it.hasNext()) {
            YgUserCultivationDay userDay = new YgUserCultivationDay();
            Entry<Long, List<YgUserCultivationOrderPrice>> orderUserCultivationByUserIdEntry = it.next();
            if (orderType.endsWith("order")) {
                userIds.add(orderUserCultivationByUserIdEntry.getKey());
            } else {
                if (!userIds.contains(orderUserCultivationByUserIdEntry.getKey())) {
                    onlyReturn.add(userDay);
                }
            }
            List<YgUserCultivationOrderPrice> valueByUserIdList = orderUserCultivationByUserIdEntry.getValue();
            /**
             * 用户id分组，按照类型
             */
            Map<RebateType, List<YgUserCultivationOrderPrice>> orderUserCultivationByTypeMap = valueByUserIdList.stream()
                    .collect(Collectors.groupingBy(e -> e.getRebateType()));
            /**
             * 循环推荐类型
             */
            List<YgUserCultivationOrderPrice> foreverList = orderUserCultivationByTypeMap.get(RebateType.Forever);

            List<YgUserCultivationOrderPrice> shareList = orderUserCultivationByTypeMap.get(RebateType.Share);

            List<String> orderIds = new ArrayList<String>();
            if (foreverList != null) {
                for (YgUserCultivationOrderPrice forever : foreverList) {
                    orderIds.add(forever.getOrderId());
                }
            }
            if (shareList != null) {
                for (YgUserCultivationOrderPrice share : shareList) {
                    if (orderIds.contains(share.getOrderId())) {
                        continue;
                    }
                    if (foreverList == null) {
                        foreverList = new ArrayList<YgUserCultivationOrderPrice>();
                    }
                    foreverList.add(share);
                }
            }

            BigDecimal orderSum = new BigDecimal("0.00");
            BigDecimal returnSum = new BigDecimal("0.00");
            if (!CollectionUtils.isEmpty(foreverList)) {

                for (YgUserCultivationOrderPrice ygUserCultivationOrderPrice : foreverList) {
                    if (orderType.endsWith("order")) {

                        orderSum = orderSum.add(ygUserCultivationOrderPrice.getOrderPrice());
                    } else {
                        returnSum = returnSum.add(ygUserCultivationOrderPrice.getReturnPrice());

                    }
                }
            }
            userDay.setUserId(orderUserCultivationByUserIdEntry.getKey());
            userDay.setOrderPrice(orderSum);
            userDay.setReturnPrice(returnSum);
            userDay.setTotalPrice(orderSum.subtract(returnSum));
            userDay.setDay(date);
            userCultiveationDayList.add(userDay);
        }

        return userCultiveationDayList;

    }

    @Override
    public void sendGrowthFundMsg() {

        ygTaskTimeService.execute(TaskMethod.SendGrowthFundMsg, 5, new YgTaskTimeTemplate() {

            @Override
            public void execute(Date date) {

                Date startTime = DateConvertUtils.addMinute(date, -5);
                Date endTime = date;
                List<YgUserBalanceDetail> list = ygUserBalanceDetailService.findDetailByTime(BalanceType.Balance, startTime, endTime);

                for (YgUserBalanceDetail d : list) {

                    if (d.getBalancePrice().compareTo(new BigDecimal("0")) <= 0) {
                        continue;
                    }
                    String title = "亲，你有一笔新的成长基金到账哦。";
                    StringBuilder content = new StringBuilder();
                    Boolean isSend = false;
                    content.append(d.getOperationType().getTitle());
                    String orderAbout = "Forever, Share, Reward, ReturnOrder, CancelOrder,WithdrawFail";
                    OperationType operationType = d.getOperationType();
                    int i = orderAbout.indexOf(operationType.name());
                    if (i >= 0) {
                        isSend = true;
                        content.append("(" + d.getOrderId() + ")");
                    }
                    if (operationType.equals(OperationType.PullNEW)) {
                        isSend = true;
                        String phone = YgStringUtils.encryptionPhone(d.getOrderId());
                        content.append("(" + phone + ")");
                    }
                    if (operationType.equals(OperationType.Activity) || operationType.equals(OperationType.Recharge)) {
                        isSend = true;
                    }

                    if (isSend) {
                        wxMpMessageService.sendGrowthFundMsg(title, d.getBalancePrice(), d.getCreateTime(), content.toString(), d.getUserId());
                    }
                }
                // ygTaskTimeService.saveOrUpdate(TaskMethod.SendGrowthFundMsg.name(),
                // date, "执行成功");
            }
        });
    }

    @Deprecated
    @Override
    public void groupOrderIncompleteReminder() {
        ygTaskTimeService.execute(TaskMethod.GroupOrderIncompleteReminder, TaskMethod.GroupOrderIncompleteReminder.getCode(), new YgTaskTimeTemplate() {

            @Override
            public void execute(Date runTime) {
                Date startTime = DateConvertUtils.addMinute(runTime, -65);
                Date endTime = DateConvertUtils.addMinute(runTime, -60);
                List<YgGroupOrderRemindModel> list = ygGroupBuyingService.findGroupOrderIncompleteReminder(endTime, startTime, endTime);
                for (YgGroupOrderRemindModel model : list) {
                    String title = "亲，您的拼团商品 " + model.getProductName() + " 件数还不够哦。";
                    long[] times = DateConvertUtils.getDistanceTimes(new Date(), DateConvertUtils.addMinute(model.getGbCreateTime(), 12 * 60));
                    String lastTime = times[1] + "小时" + times[2] + "分钟";

                    Long lastAmount = 0L;
                    if (model.getGroupAmount() != null) {
                        lastAmount = model.getGroupAmount() - model.getFinishAmount();
                    }
                    if (lastAmount > 0) {
                        // 到某团长页
                        String url = promotionLink + "/product/groupdetail.html?productId=" + model.getProductId() + "&tuanId=" + model.getGbId();
                        wxMpMessageService.sendGroupOrderRemindMsg(title, lastTime, lastAmount, url, model.getOrderUserId());
                    }
                }
                // ygTaskTimeService.saveOrUpdate(TaskMethod.GroupOrderIncompleteReminder.name(),
                // runTime, "执行成功");
            }

        });

    }

    @Deprecated
    @Override
    public void groupOrderComplete() {
        ygTaskTimeService.execute(TaskMethod.GroupOrderComplete, TaskMethod.GroupOrderComplete.getCode(), new YgTaskTimeTemplate() {

            @Override
            public void execute(Date runTime) {
                List<Long> orderIds = new ArrayList<Long>();
                Date startTime = DateConvertUtils.addMinute(runTime, -5);
                List<YgGroupOrderRemindModel> list = ygGroupBuyingService.findGroupBuy4Complete(startTime, runTime);

                Map<Long, List<YgGroupOrderRemindModel>> collect = list.stream().collect(Collectors.groupingBy(gb -> gb.getGbId()));
                List<TemplateMessage> msgList = new ArrayList<TemplateMessage>();
                List<YgGroupBuying> gbList = new ArrayList<YgGroupBuying>();
                for (Long key : collect.keySet()) {

                    List<YgGroupOrderRemindModel> models = collect.get(key);
                    // 真是完成
                    Boolean isComplete = false;
                    // 到达规定时间
                    Boolean arrivalTime = false;
                    Long groupAmount = models.get(0).getGroupAmount() == null ? 0L : models.get(0).getGroupAmount();
                    Long finishAmount = models.get(0).getFinishAmount();
                    Date completeTime = models.get(0).getCompleteTime();
                    Date realCompleteTime = runTime;
                    if (groupAmount.compareTo(finishAmount) <= 0) {
                        isComplete = true;
                    }
                    if (runTime.after(completeTime)) {
                        arrivalTime = true;
                        realCompleteTime = completeTime;
                    }
                    if (isComplete || arrivalTime) {
                        YgGroupBuying group = new YgGroupBuying(key, CompleteStatus.Complete, realCompleteTime, runTime);
                        gbList.add(group);

                        for (YgGroupOrderRemindModel buy : models) {
                            orderIds.add(buy.getOrderId());
                            getGroupOrderCompleteMsg(buy.getOrderUserId(), buy.getOrderId(), buy.getTotalPrice(), buy.getProductName(), msgList);
                        }
                    }

                }

                // 同步订单
                ygAsynClient.syncQybOrder(orderIds);
                // 更新拼团状态
                ygGroupBuyingService.updateGbForCompleteBatch(gbList);
                // 发送消息
                if (msgList.size() > 0) {
                    msgList.forEach(msg -> {
                        wxMpMessageService.sendTemplateMessage(msg);
                    });
                }

                // ygTaskTimeService.saveOrUpdate(TaskMethod.GroupOrderComplete.name(),
                // runTime, "执行成功");
            }
        });
    }

    private void getGroupOrderCompleteMsg(Long userId, Long orderId, BigDecimal totalPrice, String productName, List<TemplateMessage> msgList) {
        YgUser user = ygUserService.findById(userId);
        if (StringUtil.isEmpty(user.getOpenId())) {
            // logger.error("拼团未成功提醒消息失败，该用户没有openId");
        } else {

            String tempId = wxMpMessageService.getWxMsgTempId(WxMessageType.GroupOrderComplete);

            String title = "亲，恭喜您在壹果拼团成功哦。";
            String url = promotionLink + "/user/orderdetail.html?orderId=" + orderId;
            TemplateMessage tplMessage = new TemplateMessage(user.getOpenId(), tempId, title, url);

            tplMessage.pushHead("#323232", title);
            tplMessage.pushItem("keyword1", "#323232", productName);
            tplMessage.pushItem("keyword2", "#323232", "¥" + totalPrice);
            tplMessage.pushItem("remark", "#323232", "点击进入订单详情页，查看订单信息。 ");

            msgList.add(tplMessage);
        }
    }

    @Override
    public void monitorPushOrderToWDT() {
        Date currentDate = new Date();

        List<OrderNotPushModel> list = orderService.findOrderNotPush(currentDate);
        List<Long> orderIds = new ArrayList<Long>();
        for (OrderNotPushModel order : list) {
            if (order.getOrderType().equals(OrderType.CardCoupon)) {
                continue;
            }
            if (order.getOrderType().equals(OrderType.GroupBuying) && !order.getOrderId().toString().startsWith("9")) {
                YgGroupBuying groupBuying = ygGroupBuyingService.findById(order.getReleationId());
                if (groupBuying.getCompleteStatus().equals(CompleteStatus.Complete)) {
                    orderIds.add(order.getOrderId());
                    if (OrderStatus.WaitingCheck.equals(order.getOrderStatus())) {
                        orderService.updateOrderStatusByOrderId(OrderStatus.WaitingSend, order.getOrderId());
                    }
                }
            } else {
                orderIds.add(order.getOrderId());
            }
        }
        ygAsynClient.syncQybOrder(orderIds);
        // logger.error(orderIds.toString());
        ygTaskTimeService.saveOrUpdate("MonitorPushOrderToWDT", currentDate, "执行成功");
    }

    @Override
    public void sendKanJiaInvitation() {
        ygTaskTimeService.execute(TaskMethod.SendKanJiaInvitation, 5, new YgTaskTimeTemplate() {

            @Override
            public void execute(Date date) throws Exception {
                List<YgUserBargain> list = ygUserBargainService.findUserBargainLastOneHour(DateConvertUtils.addMinute(date, -5), date);
                for (YgUserBargain ub : list) {
                    YgUser user = ygUserService.findById(ub.getUserId());
                    String to = user.getOpenId();
                    String url = "http://m.yiigoo.com/bargain/details.html?sourcePage=my&bargainId=" + ub.getId();
                    Text notifyTuple = new Text("<a href='" + url + "'>剁手活动还有1小时就要结束啦，邀请更多小伙伴帮你砍价吧！</a>");
                    if (StringUtil.isNotBlank(to)) {
                        wxMpMessageService.sendCustomMsg(notifyTuple, to);
                    }
                }

            }
        });
    }

    @Override
    public void sendCoupon1111(Date limitDate) {
        Date endDate = DateConvertUtils.parse("2017-11-11", DateConvertUtils.DATE_FORMAT);
        // DOTO 上线改批次
        YgCoupon coupon = couponService.findById(225L);

        List<YgTaskTime> task = ygTaskTimeService.findByName("sendCoupon1111");
        Date runTime = task.get(0).getRunTime();
        if (runTime.before(limitDate)) {
            Date start = DateConvertUtils.getDateStart(runTime);
            Date end = DateConvertUtils.addDay(start, 1);
            String[] status = {OrderStatus.WaitingSend.name(), OrderStatus.WaitingSign.name(), OrderStatus.TradeSuccess.name()};

            List<YgOrder> list = orderService.findByCreateTime(start, end, Arrays.asList(status));

            ygRepairDataService.sendCoupon1111(list, coupon, endDate, "sys");
            ygTaskTimeService.saveOrUpdate("sendCoupon1111", end, "ok");

        }

    }

}